package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.domain.TOrderInfo;
import com.ruoyi.business.domain.TOrderQrcodeInfo;
import com.ruoyi.business.domain.TRecipientInfo;
import com.ruoyi.business.param.MsgPayResult;
import com.ruoyi.business.response.ErrorResponseData;
import com.ruoyi.business.response.ResponseData;
import com.ruoyi.business.response.SuccessResponseData;
import com.ruoyi.business.service.BasePayment;
import com.ruoyi.business.service.ChargeService;
import com.ruoyi.business.service.ITOrderQrcodeInfoService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.payment.pbqzpay.PubuPayUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service("wxskdPayService")
public class WechatSkdPayServiceImpl extends BasePayment {


    @Resource
    private ChargeService chargeService;

    @Resource
    private ITOrderQrcodeInfoService itOrderQrcodeInfoService;

    @Override
    public JSONObject createPayOrder(TOrderInfo orderInfo) throws Exception {
        JSONObject jsonObject = new JSONObject();
        TRecipientInfo userRecipientInfo = userRecipientService.selectTRecipientInfoById(orderInfo.getRecipientId());
        HashMap<String, String> headerMap = new HashMap();
        HashMap<String, String> dataMap = new HashMap();
        headerMap.put("User-Agent","Mozilla/5.0 (iPhone; CPU iPhone OS 17_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.53(0x18003531) NetType/4G Language/zh_CN");
        headerMap.put("Connection","keep-alive");
        headerMap.put("content-type","application/json");
        headerMap.put("Accept-Encoding","gzip,compress,br,deflate");
        String payInfo = "";
        String regionCode = "";
        if (StringUtils.isNotBlank(userRecipientInfo.getCity())) {
            regionCode = userRecipientInfo.getCity();
        } else if (StringUtils.isNotBlank(userRecipientInfo.getProvince())) {
            regionCode = userRecipientInfo.getProvince();
        }
        JSONObject proxyObj = new JSONObject();
        if (StringUtils.isNotBlank(regionCode)) {
            proxyObj = commonService.getPoxyIp(regionCode);
            orderInfo.setProxyIp(proxyObj.getString("ip") + ":" + proxyObj.getString("prot"));
        }
        String accountJson = userRecipientInfo.getAccountJson();
        JSONObject  accountObj = JSONObject.parseObject(accountJson);
        String ck = accountObj.getString("ck");
        String sid = getParamByUrl(ck, "sid");
        String miniprogram_version =accountObj.getString("miniprogram_version");

        String account_id = accountObj.getString("account_id");
        String account_type = accountObj.getString("account_type");
        if(StringUtils.isBlank(account_id) || StringUtils.isBlank(account_type) || StringUtils.isBlank(sid)){
            String accountUrl = "https://payapp.wechatpay.cn/receiptwxmgr/account/list?miniprogram_version="+miniprogram_version+"&sid="+sid;
            HttpResponse accountResponse =  HttpUtils.httpFormGet(accountUrl,headerMap,"","","");
            JSONObject  accountResponseObj  = JSONObject.parseObject(accountResponse.getBody());
            logger.info("返回：{}",accountResponseObj.toJSONString());
            if(accountResponseObj.getInteger("errcode")!=0){
                logger.info("========修改收款账号为不可用===============");

                userRecipientInfo.setOnline(0);
                userRecipientInfo.setDisabledInfo(accountResponseObj.getString("msg"));
                userRecipientService.updateTRecipientInfo(userRecipientInfo);
                jsonObject.put("code","200");
                jsonObject.put("msg","生成收款单失败:"+"检测CK失败："+accountResponseObj.getString("msg"));
                return jsonObject;
            }
            JSONArray account_list = accountResponseObj.getJSONObject("data").getJSONArray("account_list");
            JSONObject wxaccountObj = null;
            for (int i = 0; i < account_list.size(); i++) {
                JSONObject account = account_list.getJSONObject(i);
                if(account.getString("account_type").equals("2")){
                    wxaccountObj = account;
                    break;
                }
            }
            if(wxaccountObj==null){
                userRecipientInfo.setOnline(0);
                userRecipientInfo.setDisabledInfo(accountResponseObj.getString("msg"));
                userRecipientService.updateTRecipientInfo(userRecipientInfo);
                jsonObject.put("code","200");
                jsonObject.put("msg","生成收款单失败:"+"检测CK失败：获取账号信息失败");
                return jsonObject;
            }

            account_id = wxaccountObj.getString("account_id");
            account_type = wxaccountObj.getString("account_type");
            String account_name = wxaccountObj.getString("account_name");
            String  account_status = wxaccountObj.getString("account_status");
            if(!account_status.equals("ACTIVATED")){
                logger.info("========修改收款账号为不可用===============");
                userRecipientInfo.setOnline(0);
                userRecipientInfo.setDisabledInfo("账号状态异常");
                userRecipientService.updateTRecipientInfo(userRecipientInfo);
                jsonObject.put("code","200");
                jsonObject.put("msg","生成收款单失败:"+"检测CK失败：收款账号状态异常");
                return jsonObject;
            }
            accountObj.put("miniprogram_version", miniprogram_version);
            accountObj.put("account_id", account_id);
            accountObj.put("account_type", account_type);
            accountObj.put("sid", sid);
            userRecipientInfo.setAccountJson(accountObj.toJSONString());
            userRecipientInfo.setRealName(account_name);
            userRecipientInfo.setOnline(1);
            userRecipientService.updateTRecipientInfo(userRecipientInfo);
        }
        //https://payapp.wechatpay.cn/receiptwxmgr/receipt/create?miniprogram_version=3.15.9&fee=38800&remark=&remark_pic_urls=&option_list=%5B%5D&receipt_item_list=%5B%5D&account_id=oMdKm5KMy6CkQKQPBYMrPgXbqQy0&account_type=2&sid=BAEr4V2l1ETngo7y0M_HGAyJWoFpW8qktiH0qUZnGQRDNA

        String submitPayUrl = "https://payapp.wechatpay.cn/receiptwxmgr/receipt/create?miniprogram_version="+miniprogram_version+"&fee="+orderInfo.getMoney()+"&remark=&remark_pic_urls=&option_list=%5B%5D&receipt_item_list=%5B%5D&account_id="+account_id+"&account_type="+account_type+"&sid="+sid;
        logger.info("create请求参数：{}",submitPayUrl);
        int retryCount = 0;
        HttpResponse submResponse = null;
        if (StringUtils.isNotBlank(regionCode)) {
//            proxyObj = commonService.getPoxyIp(regionCode);
//            orderInfo.setProxyIp(proxyObj.getString("ip") + ":" + proxyObj.getString("prot"));
            submResponse = HttpUtils.httpFormGet(submitPayUrl,headerMap,"","",orderInfo.getProxyIp());
        }else{
            submResponse = HttpUtils.httpFormGet(submitPayUrl,headerMap,"","","");
        }

        if(!submResponse.getIsSuccess()){
            submResponse = reGetUrl(orderInfo,submitPayUrl,regionCode,retryCount);
            if(submResponse == null){
                jsonObject.put("code","200");
                jsonObject.put("msg","生成收款单失败:"+submResponse.getMessage());
                logger.info("========修改收款账号为不可用==============="+submResponse.getMessage());
                userRecipientInfo.setOnline(0);
                userRecipientInfo.setDisabledInfo("生成收款单失败："+submResponse.getMessage());
                userRecipientService.updateTRecipientInfo(userRecipientInfo);
                return jsonObject;
            }
        }
        JSONObject  submResponseObj  = JSONObject.parseObject(submResponse.getBody());
        logger.info("create返回：{}",submResponseObj.toJSONString());
        if(submResponseObj.getInteger("errcode")!=0){
            jsonObject.put("code","200");
            jsonObject.put("msg","生成收款单失败:"+submResponseObj.getString("msg"));
            logger.info("========修改收款账号为不可用==============="+submResponseObj.toJSONString());
            userRecipientInfo.setOnline(0);
            userRecipientInfo.setDisabledInfo("生成收款单失败："+submResponseObj.toJSONString());
            userRecipientService.updateTRecipientInfo(userRecipientInfo);
            return jsonObject;
        }
        String receipt_id = submResponseObj.getJSONObject("data").getJSONObject("receipt").getString("receipt_id");

        //https://payapp.wechatpay.cn/receiptwxmgr/receipt/getwxacode?miniprogram_version=3.15.9&wxacode_path_type=1&receipt_id=27328862&account_id=oMdKm5KMy6CkQKQPBYMrPgXbqQy0&account_type=2&sid=BAEr4V2l1ETngo7y0M_HGAyJWoFpW8qktiH0qUZnGQRDNA
        String createUrl = "https://payapp.wechatpay.cn/receiptwxmgr/receipt/getwxacode?miniprogram_version="+miniprogram_version+"&wxacode_path_type=1&receipt_id="+receipt_id+"&account_id="+account_id+"&account_type="+account_type+"&sid="+sid;
        logger.info("getwxacode请求参数：{}",createUrl);
        HttpResponse createResponse = null;
        if (StringUtils.isNotBlank(regionCode)) {
//            proxyObj = commonService.getPoxyIp(regionCode);
//            orderInfo.setProxyIp(proxyObj.getString("ip") + ":" + proxyObj.getString("prot"));
            createResponse = HttpUtils.httpFormGet(createUrl,headerMap,"","",orderInfo.getProxyIp());
        }else{
            createResponse = HttpUtils.httpFormGet(createUrl,headerMap,"","","");
        }
        if(!createResponse.getIsSuccess()){
            createResponse = reGetUrl(orderInfo,createUrl,regionCode,0);
            if(createResponse == null){
                jsonObject.put("code","200");
                jsonObject.put("msg","生成收款单失败:重试生成3次还是失败");
                logger.info("========修改收款账号为不可用===============重试生成3次还是失败");
                userRecipientInfo.setOnline(0);
                userRecipientInfo.setDisabledInfo("生成收款单失败：重试生成3次还是失败");
                userRecipientService.updateTRecipientInfo(userRecipientInfo);
                return jsonObject;
            }
        }
        JSONObject  createResponseObj  = JSONObject.parseObject(createResponse.getBody());
//        logger.info("getwxacode返回：{}",createResponseObj.toJSONString());
        if(createResponseObj.getInteger("errcode")!=0){

            jsonObject.put("code","200");
            jsonObject.put("msg","生成收款单失败"+createResponseObj.getString("msg"));
            logger.info("========修改收款账号为不可用==============="+createResponseObj.toJSONString());
            userRecipientInfo.setOnline(0);
            userRecipientInfo.setDisabledInfo("生成收款单失败"+createResponseObj.toJSONString());
            userRecipientService.updateTRecipientInfo(userRecipientInfo);
            return jsonObject;
        }
        String qrcode = createResponseObj.getJSONObject("data").getString("qrcode");
        TOrderQrcodeInfo tOrderQrcodeInfo = new TOrderQrcodeInfo();
        tOrderQrcodeInfo.setOrderId(orderInfo.getId());
        List<TOrderQrcodeInfo> list = itOrderQrcodeInfoService.selectTOrderQrcodeInfoList(tOrderQrcodeInfo);
        tOrderQrcodeInfo.setQrcodeContent(qrcode);
        if(list!=null && list.size()>0){
            itOrderQrcodeInfoService.updateTOrderQrcodeInfo(tOrderQrcodeInfo);
        }else{
            itOrderQrcodeInfoService.insertTOrderQrcodeInfo(tOrderQrcodeInfo);
        }
//        orderInfo.setQrcodeContent(qrcode);
        orderInfo.setQrcodeTxt(receipt_id);
        orderInfoService.updateTOrderInfo(orderInfo);
//        logger.info("微信收款单请求返回:{}",createResponseObj.toJSONString());
        jsonObject.put("payUrl",orderInfo.getPayUrl());
        jsonObject.put("orderNo","");
        jsonObject.put("code","200");
        return jsonObject;
    }


    public JSONObject createWxPayOrder(TOrderInfo orderInfo) throws ServiceException, UnsupportedEncodingException {
        return null;
    }


    private HttpResponse reGetUrl(TOrderInfo orderInfo,String submitPayUrl,String regionCode,int i) {
        logger.info("=============重试次数=========={}",i);
        if(i>5){
            return null;
        }
        HashMap<String, String> headerMap = new HashMap();
        HttpResponse submResponse = HttpUtils.httpFormGet(submitPayUrl,headerMap,"","",orderInfo.getProxyIp());
        if(!submResponse.getIsSuccess()){
            JSONObject proxyObj = commonService.getPoxyIp(regionCode);
            orderInfo.setProxyIp(proxyObj.getString("ip") + ":" + proxyObj.getString("prot"));
            i++;
           return reGetUrl(orderInfo, submitPayUrl,regionCode,i);
        }
        return submResponse;
    }

    private JSONObject reSubmit(TRecipientInfo tRecipientInfo,JSONObject  reqOrderObj) {
        long time = System.currentTimeMillis()/1000;
        String accountJson = tRecipientInfo.getAccountJson();
        JSONObject  accountObj = JSONObject.parseObject(accountJson);
        HashMap<String, String> headerMap = new HashMap();
        String token = accountObj.getString("token");
        String sign = PubuPayUtils.getSign(time,reqOrderObj,token);
        String submitPayUrl = "http://api.openpubu.com/order/submitFtfpayOrder?token="+token+"&time="+time+"&sign="+sign+"&client_channel=2&api_version=2.2.5";
        String submitPayRes = HttpUtils.sendJsonMessage(submitPayUrl,headerMap,reqOrderObj.toJSONString());
        JSONObject  submitPayResObj = JSONObject.parseObject(submitPayRes);
        return submitPayResObj;
    }

    @Override
    public ResponseData smartReissueOrder(TOrderInfo orderInfo) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        synchronized (this) {
            if (StringUtils.isBlank(orderInfo.getQrcodeTxt())) {
                return new ErrorResponseData("未获取微信官方订单号");
            }
            TRecipientInfo userRecipientInfo = userRecipientService.selectTRecipientInfoById(orderInfo.getRecipientId());
            String accountJson = userRecipientInfo.getAccountJson();
            JSONObject accountObj = JSONObject.parseObject(accountJson);
            String regionCode = "";
            if (StringUtils.isNotBlank(userRecipientInfo.getCity())) {
                regionCode = userRecipientInfo.getCity();
            } else if (StringUtils.isNotBlank(userRecipientInfo.getProvince())) {
                regionCode = userRecipientInfo.getProvince();
            }
            JSONObject proxyObj = new JSONObject();
            if (com.ruoyi.common.utils.StringUtils.isNotBlank(regionCode)) {
                proxyObj = commonService.getPoxyIp(regionCode);
            }
            String account_id = accountObj.getString("account_id");
            String account_type = accountObj.getString("account_type");
            String sid = accountObj.getString("sid");
            String miniprogram_version = accountObj.getString("miniprogram_version");
            HashMap<String, String> headerMap = new HashMap();
//                headerMap.put("Cookie", accountObj.getString("cookie"));
            headerMap.put("User-Agent","Mozilla/5.0 (iPhone; CPU iPhone OS 17_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.53(0x18003531) NetType/4G Language/zh_CN");
            headerMap.put("Connection","keep-alive");
            headerMap.put("content-type","application/json");
            headerMap.put("Accept-Encoding","gzip,compress,br,deflate");

            String qryUrl ="https://payapp.wechatpay.cn/receiptwxmgr/receipt/detail?miniprogram_version="+miniprogram_version+"&receipt_id="+orderInfo.getQrcodeTxt()+"&page_index=1&page_size=10&account_id="+account_id+"&account_type="+account_type+"&sid="+sid;
            HttpResponse submResponse =  null;
//            if (StringUtils.isNotBlank(regionCode)) {
//                submResponse = HttpUtils.httpFormGet(qryUrl,headerMap,"","",proxyObj.getString("ip") + ":" + proxyObj.getString("prot"));
//            }else{
//            }
            submResponse = HttpUtils.httpFormGet(qryUrl,headerMap,"","","");

            JSONObject result = JSONObject.parseObject(submResponse.getBody());
            logger.info("查单返回：{}", result);
            if(result.getInteger("errcode")==0){
                JSONArray orderList = result.getJSONObject("data").getJSONObject("receipt").getJSONArray("order");
                for (int i = 0; i < orderList.size(); i++) {
                    JSONObject order = orderList.getJSONObject(i);
                    if(!order.getString("state").equals("STATE_PAY_SUCCESS")){
                        continue;
                    }
                    long pay_succ_time = order.getLongValue("pay_succ_time");
                    pay_succ_time *= 1000;
                    Date payTime = new Date(pay_succ_time);
                    boolean flag = false;
                    if (payTime.after(orderInfo.getCreateTime()) && payTime.before(orderInfo.getValidTime())) {
                        logger.info("订单修改时间：{},订单支付时间:{},订单失效时间：{}", sdf.format(orderInfo.getUpdateTime()), sdf.format(payTime), sdf.format(orderInfo.getValidTime()));
                        flag = true;
                    }
                    if(flag){
                        MsgPayResult msgPayResult = new MsgPayResult();
                        msgPayResult.setChannel(orderInfo.getChannel());
                        msgPayResult.setTradeNo(orderInfo.getId().toString());
                        msgPayResult.setChannelAccount(userRecipientInfo.getChannelAccount());
                        msgPayResult.setOrderId(order.getString("transaction_id"));
                        msgPayResult.setRealMoney(MoneyUtil.fenToYuan(orderInfo.getMoney() + ""));
                        msgPayResult.setUid(userRecipientInfo.getUserId().toString());
                        msgPayResult.setBillTime(sdf.format(payTime));
                        msgPayResult.setChannelPayMsgResult(result.toJSONString());
                        ResponseData responseData = chargeService.updateOrderPayResult(true, orderInfo.getId(), msgPayResult, false);
                        logger.info("【智能补单】微信收款单回调..订单号：" + orderInfo.getId() + " 金额：" + orderInfo.getMoney() + " 处理结果：{}", responseData.getSuccess());
                        chargeService.notifyUserPaySucc(orderInfo.getId());
                    }
                }
            }else{
                return new ErrorResponseData(result.getString("msg"));
            }
        }
        return new SuccessResponseData();
    }
}
